package awk.jdk8.functionalInterface;

import lombok.extern.slf4j.Slf4j;

import java.util.function.Function;

/**
 * created with IDEA
 *
 * @author haifeng.wang
 * @since 2019-05-31-18:04
 */
@Slf4j
public class FunctionTest {
    //Function<T,R> 接受一个输入参数，返回一个结果

    public static void main(String[] args) {
        Function<Integer, Integer> param = i -> i * 10;
        Integer integer =  param.apply(3);
        log.info("" + integer);

        Function<Integer, Integer> before = i -> i * i;
        Function<Integer, Integer> after = i -> i * 2;
        /**
         * compose方法是Function接口提供的，是一个泛型接口,Function.compose(Function<? super V, ? extends T> before)
         * 先执行 before.apply() , 再执行 compose
         * 先执行 before.apply(),然后 after.compose(before)是在 before.apply()执行结果之上
         */
        int i1 = after.compose(before).apply(5);
        log.info("" + i1);
        int i2 = before.andThen(after).apply(5);
        log.info("" ,i2);


        /**
         * 级联表达式和柯里化
         * 柯里化:把多个参数的函数转换为只有一个参数的函数
         * 柯里化的目的：函数标准化
         * 高阶函数：就是返回函数的函数
         */
        // 实现了x+y的级联表达式
        Function<Integer, Function<Integer, Integer>> fun = x -> y -> x + y;
        //这样表达更容易读懂
        //Function<Integer, Function<Integer, Integer>> fun3 = (x) -> ((y) ->( x + y));
        Integer apply = fun.apply(2).apply(3); // x=2, y=3
        System.out.println(apply);

        Function<Integer, Function<Integer, Function<Integer, Integer>>> fun2 = x -> y -> z -> x + y + z;
        Integer apply1 = fun2.apply(2).apply(3).apply(4);
        System.out.println(apply1);

        int[] nums = { 2, 3, 4 };
        // 柯里化后可以循环调用
        for (int i = 0; i < nums.length; i++) {
            if (fun2 instanceof Function) {
                Object obj = fun2.apply(nums[i]);
                if (obj instanceof Function) {
                    fun2 = (Function) obj;
                } else {
                    System.out.println("调用结束：结果为" + obj);
                }
            }
        }
    }
}
